using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

using miciv;
using micivCore.Faction;

namespace micivCore.Xml
{
    public class XmlListenerFaction : XmlListener
    {
        protected FactionManager m_factionManager;
        protected Faction.Faction m_currentFaction;
        protected FactionGroup m_currentFactionGroup;
        protected FactionHierarchy m_hierarchy;

        public XmlListenerFaction()
        {
            this.Subscribe("factions", this.factionsStartTagEventHandler, this.factionsEndTagEventHandler);
            this.Subscribe("faction", this.factionStartTagEventHandler, this.factionEndTagEventHandler);
            this.Subscribe("hierarchy", this.hierarchyStartTagEventHandler, this.hierarchyEndTagEventHandler);
            this.Subscribe("entity", this.entityStartTagEventHandler, this.entityEndTagEventHandler);
            this.Subscribe("groups", this.groupsStartTagEventHandler, this.groupsEndTagEventHandler);
            this.Subscribe("group", this.groupStartTagEventHandler, this.groupEndTagEventHandler);
        }

        public void Initialize(FactionManager _factionManager, CoreContext _coreContext, XmlTraverser _xmlTraverser)
        {
            base.Initialize(_coreContext, _xmlTraverser);
            this.m_factionManager = _factionManager;
        }

        protected bool factionsStartTagEventHandler(string _strName, XmlAttributeCollection _xmlAttributes)
        {
            return true;
        }

        protected bool factionsEndTagEventHandler(string _strName)
        {
            return true;
        }

        protected bool factionStartTagEventHandler(string _strName, XmlAttributeCollection _xmlAttributes)
        {
            if (null == this.m_currentFaction)
            {
                this.m_currentFaction = new Faction.Faction(this.m_coreContext);
                if ((0 < _xmlAttributes.Count)
                    && (false != this.m_currentFaction.Initialize(_xmlAttributes[0].OwnerElement))
                    && (null == this.m_factionManager.Get(this.m_currentFaction.ID)))
                {
                    this.m_factionManager.Add(this.m_currentFaction.ID, this.m_currentFaction);
                    return true;
                }
            }
            return false;
        }

        protected bool factionEndTagEventHandler(string _strName)
        {
            if (null != this.m_currentFaction)
            {
                this.m_currentFaction = null;
                return true;
            }
            return false;
        }

        protected bool hierarchyStartTagEventHandler(string _strName, XmlAttributeCollection _xmlAttributes)
        {
            if ((null != this.m_currentFaction) && (null == this.m_hierarchy))
            {
                this.m_hierarchy = this.m_currentFaction.Hierarchy;
                return true;
            }
            return false;
        }

        protected bool hierarchyEndTagEventHandler(string _strName)
        {
            if (null != this.m_hierarchy)
            {
                this.m_hierarchy = null;
                return true;
            }
            return false;
        }

        protected bool entityStartTagEventHandler(string _strName, XmlAttributeCollection _xmlAttributes)
        {
            if (null != this.m_currentFactionGroup)
            {
                string strID = this.m_coreContext.CoreManager.GetXmlAttributeValue(_xmlAttributes, "id", "");
                EntityPrototype prototype = this.m_coreContext.CoreManager.GetEntityPrototype(strID);
                if (null == prototype)
                {
                    throw new Exception(string.Format("{0} : could not find entity {1}", _xmlAttributes[0].OwnerDocument.BaseURI, strID));
                }
                this.m_currentFactionGroup.AddEntityPrototype(prototype);
                return true;
            }
            if (null != this.m_hierarchy)
            {
                return true;
            }
            return false;
        }

        protected bool entityEndTagEventHandler(string _strName)
        {
            return true;
        }

        protected bool groupsStartTagEventHandler(string _strName, XmlAttributeCollection _xmlAttributes)
        {
            return true;
        }

        protected bool groupsEndTagEventHandler(string _strName)
        {
            return true;
        }

        protected bool groupStartTagEventHandler(string _strName, XmlAttributeCollection _xmlAttributes)
        {
            if ((null != this.m_currentFaction) && (null == this.m_currentFactionGroup))
            {
                string strID = this.m_coreContext.CoreManager.GetXmlAttributeValue(_xmlAttributes, "id", "");
                this.m_currentFactionGroup = this.m_currentFaction.GetGroup(strID, true);
                return true;
            }
            return false;
        }

        protected bool groupEndTagEventHandler(string _strName)
        {
            if (null != this.m_currentFactionGroup)
            {
                this.m_currentFactionGroup = null;
                return true;
            }
            return false;
        }
    }
}
